Redis实现原子操作的两种方式与商品入库出库解决方案 您所在的位置:网站首页 redis 原子操作 Redis实现原子操作的两种方式与商品入库出库解决方案

Redis实现原子操作的两种方式与商品入库出库解决方案

2024-05-21 02:49| 来源: 网络整理| 查看: 265

在单机的Redis集群下,想要实现针对多个key的复杂原子操作有两种方法。一种是Watch+Multi,即监视器加事务方式,另一种便是通过执行lua脚本实现。

这里所说的复杂原子性操作比如,扣减某商品的5个库存,需要先判断当前商品的剩余库存是否足够扣减。但是避免不了在判断足够的情况下,再去执行扣减库存操作时,这个期间库存没有被别人修改的情况。

1

Watch+Multi

Watch可以监控多个key,被监听的多个key,只要其中有一个key被修改,那么所有操作都不会被执行,即事务不会执行。Watch并不能单独使用,而是要结合事务使用。

截图漏掉了Watch s1 s2

接着我们看下,在Watch之后,事务执行之前,如果key被修改,会是什么情况。

这很好理解,即便事务中各命令的顺序不一样,因为单线程执行命令的原因,exec执行时就已经知道被监听的哪些key被修改过了,然后就不执行事务了。

每个Redis数据库中都保存着一个watched_keys的字典,这个字典的键是某个被Watch命令监视的键,如上面例子中的s1 s2,而字典的值则是一个链表,链表中记录所有监视该键的客户端,即一个连接。

所有写命令,在执行之后都会对watched_keys字典进行检查,查看是否有客户端正在监视刚刚写的键,如果有,将监视该键的客户端的REDIS_DIRTY_CAS标识打开,表示该客户端的事务安全性已经被破坏。在客户端(一个连接)提交(exec)事务执行时,先检测该标识是否被打开,如果是,则会拒绝当前客户端执行提交的事务。

假设在Cluster集群下执行,会是什么结果呢?我在我的服务器上部署了一个cluster集群,这是很早之前就部署了的。来看下在Cluster集群下执行Watch监听多个key会怎样。

可以看到,在Watch的时候就出错了,请求不允许key在不同的slot。即便slot不同但都在同一个节点也是不行的,必须是同一个slot。下图中,s4和s5这两个key是在同一个节点上的。

Watch是真的严格,不同slot都不行。有没有想过为什么监听多个落在不同节点上的key,会不被允许?在单节点下,Redis单线程执行,能够保证原子性,但在不同节点下,就是多进程多线程的问题,Watch自然就不能用。再简单点,watched_keys字典不一样就是不行。

2

Lua脚本

Redis执行lua脚本是原子性操作,与执行Redis命令一样对待。原子性操作得益于Redis执行命令是单线程的,lua脚本也会放在命令执行的等待队列中排队执行,因此也需要特别注意,lua脚本中不要执行太多代码,最好不要写for循环语句,控制脚本的执行耗时,否则会影响Redis的性能。

在主从Redis集群与读写分离Redis集群下,lua脚本的编写不需要考虑太多问题,只需考虑脚本耗时问题。但在分槽位的cluster集群下,我们想要通过lua脚本实现原子性操作,就必须要确保脚本所要操作的key都在同一个Redis节点下,即所有key计算出来的槽位都落到同一个Redis节点(小集群中的master)下,才能保证命令是原子性的。

事实上,如果要操作的key不在同一节点上,命令执行也会保错。下图是Lua脚本试图访问群集中的非本地节点抛出的错误。

即便是在一个事务中执行多个lua脚本,只要有一个lua脚本操作的key落在不同的节点,结果都会执行失败。

并不只是lua脚本,因为事务也不支持multi与exec之间的命令,操作的key落在不同节点的情况。

不同slot也不行。

3

商品入库出库问题

关于商品库存的问题,很多视频教程都在讲使用分布式锁,你可能也会想到使用分布式锁,但是用过分布式锁的都知道性能是个什么情况。

如果商品库存只使用redis缓存,在不需要修改数据库中库存的情况下。对商品的库存实现入库和出库,我们可以借助lua脚本实现原子性修改库存。在lua脚本中判断库存是否足够减库存,足够扣减情况下再更新库存,这一系列操作是原子的。

lua脚本不难学,我看了一下条件选择、分支语句以及判断语句之后就能自己写出脚本了。因为我们也并不需要用lua做多复杂的事情。下面给出一个原子性修改库存的lua脚本例子:

代码语言:javascript复制local kc=tonumber(redis.call('GET',KEYS[1])); if kc==nil then return -1; end local newKc=kc-ARGV[1]; if newKc


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有